﻿using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

namespace Tiscs.Practices.Web.Services.Client
{
    /// <summary>
    /// Cookie管理器消息拦截器。单例模式。
    /// </summary>
    public class CookieManagerMessageInspector : IClientMessageInspector
    {
        /// <summary>
        /// Cookie管理器消息拦截器单例实例。
        /// </summary>
        private static CookieManagerMessageInspector instance;

        /// <summary>
        /// 私有构造方法。
        /// </summary>
        private CookieManagerMessageInspector()
        {
        }

        /// <summary>
        /// 获取Cookie管理器消息拦截器单例实例。
        /// </summary>
        public static CookieManagerMessageInspector Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new CookieManagerMessageInspector();
                }

                return instance;
            }
        }

        /// <summary>
        /// 在客户端收到消息支后执行。
        /// </summary>
        /// <param name="reply">接收到的消息。</param>
        /// <param name="correlationState">关联状态数据。</param>
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            HttpResponseMessageProperty httpResponse =
                reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;

            if (httpResponse != null)
            {
                string cookie = httpResponse.Headers[HttpResponseHeader.SetCookie];

                if (!string.IsNullOrEmpty(cookie))
                {
                    ServiceCookieManager.Current.ServiceCookie = cookie;
                }
            }
        }

        /// <summary>
        /// 在客户端发送消息之前执行。
        /// </summary>
        /// <param name="request">要发送的消息。</param>
        /// <param name="channel">客户端对象通道。</param>
        /// <returns>关联状态数据。</returns>
        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            HttpRequestMessageProperty httpRequest;

            if (!request.Properties.ContainsKey(HttpRequestMessageProperty.Name))
            {
                request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
            }

            httpRequest = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
            httpRequest.Headers.Add(HttpRequestHeader.Cookie, ServiceCookieManager.Current.ServiceCookie);

            return null;
        }
    }
}
